<?php

/**
 * Aurorum - Open source digital signage
 *
 * @link http://digitalsignage.tk
 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
 *
 * @category Aurorum
 * @package Aurorum
 */

/**
 * This class manages all about players.
 *
 * @package Aurorum
 * @subpackage Controllers
 */

class ADS_PlayerController extends ADS_DefaultController{
    
    const STATUS_ADD_OK    = 1;
    const STATUS_REMOVE_OK = 3;
    const STATUS_EDIT_OK   = 5;
    
    const STATUS_CMD_ADD_OK = 7;
    
    const BULK_ACTION_REMOVE = 'remove';
    
    public function handleDefaultBulkAction(){
        //get variables         
        $post   =  (array)ADS_Input::postVar('post', array());
        $action = (string)_ifset(
            ADS_Input::postVar('action1', '-1') !== '-1',
            ADS_Input::postVar('action1', '-1'),
            ADS_Input::postVar('action2', '-1')
        );
        //validate token
        if(!wp_verify_nonce(ADS_Input::postVar('token', ''), $_GET['page'].':defaultBulkAction')){
            throw new ADS_VerifyTokenException('Token mismatch.');
        }
        //parse action
        switch ($action) {            
            case self::BULK_ACTION_REMOVE:                
                    $status = $this->bulkRemovePlayers($post);                
                break;

            default:
                //action is not recognized (do nothing)
                //throw new ADS_UnknownBulkActionException('Action is not recognized.');
                break;
        }
        //redir
        ADS_Navigator::redir('self:defaultAction',array(
            'msg' => $status
        ));
    }
    
    public function bulkRemovePlayers($players){
        //validate parameters
        if(!is_array($players)){
            throw new InvalidArgumentException(sprintf('Wrong parameters for method %s.',__METHOD__));
        }
        ADS_Navigator::freeze();
        foreach ($players as $playerId) {
            $this->handleRemovePlayer((int)$playerId, false);
        }
        ADS_Navigator::unfreeze();        
    }
    
    public function handleRemovePlayer($playerId = 0, $useToken = true){
        //validate parameters
        if(!is_int($playerId) || !is_bool($useToken)){
            throw new InvalidArgumentException(sprintf('Wrong parameters for method %s.',__METHOD__));
        }
        //validate token
        if($useToken && !wp_verify_nonce(ADS_Input::getVar('token', ''), $_GET['page'].':removePlayer')){
            throw new ADS_VerifyTokenException('Token mismatch.');
        }
        $pModel = new ADS_PlayerModel();
        //get variables
        $playerId = (int)_ifset($playerId > 0, $playerId, ADS_Input::getVar('playerId', 0)); 
        $player   = $pModel->getPlayer($playerId);
        //remove player        
        $pModel->removePlayer($playerId);
        //log change
        ADS_Logger::logChange('Player "%s" was removed.', $player['name']);
        //redir
        ADS_Navigator::redir('self:defaultAction',array(
            'msg' => self::STATUS_REMOVE_OK
        ));
    }
    
    public function handleAddPlayer(){
        
        $pModel = new ADS_PlayerModel();
        //default values
        $player   = array();
        $isValid = true;
        //resolve action
        $action = ADS_Input::postVar('action', 'default');         
        switch($action){
            case 'add':
                $player['name']      = (string)ADS_Input::postVar('player.name', '');
                $player['clientKey'] = (string)ADS_Input::postVar('player.clientKey');
                //validation
                if(mb_strlen($player['name']) == 0){
                    ADS_MsgStack::push('error', sprintf('Name of player can not be blank.'));
                    $isValid = false;
                }
                if(mb_strlen($player['name']) > 0 && (mb_strlen($player['name']) < 4 || mb_strlen($player['name']) > 255)){
                    ADS_MsgStack::push('error', sprintf('Name of player must be between %d and %d characters long.', 4, 255));
                    $isValid = false;
                }
                if(mb_strlen($player['name']) > 0 && (mb_strlen($player['clientKey']) < 6 || mb_strlen($player['clientKey']) > 128)){
                    ADS_MsgStack::push('error', sprintf('Client key must be between %d and %d characters long.', 6, 128));
                    $isValid = false;
                }
                if($pModel->checkClientKey($player['clientKey'])){
                    ADS_MsgStack::push('error', sprintf('Client key already exists. Choose another one.', 6, 128));
                    $isValid = false;
                }
                
                if($isValid){
                    //insert new player to db
                    $pModel->addPlayer($player);
                    //log change
                    ADS_Logger::logChange('Player "%s" was created.', $player['name']);
                    //redir
                    ADS_Navigator::redir('self:defaultAction',array(
                        'msg' => self::STATUS_ADD_OK
                    ));
                }                
                break;                
        }  
        //add variables to output
        ADS_Output::register('player', $player);
        ADS_Output::register('errors', $errors);
        
    }
    
    public function handleEditPlayer(){
        
        $pModel = new ADS_PlayerModel();
        //default values
        $playerId = (int)ADS_Input::getVar('playerId', 0);
        $player   = $pModel->getPlayer($playerId);
        $isValid = true;
        //resolve action
        $action = ADS_Input::postVar('action', 'default');         
        switch($action){
            case 'edit':
                $clientKey = $player->clientKey;
                $player    = array();
                //get values
                $player['name']      = (string)ADS_Input::postVar('player.name', '');
                $player['clientKey'] = (string)ADS_Input::postVar('player.clientKey');
                //validation
                if(mb_strlen($player['name']) == 0){
                    ADS_MsgStack::push('error', sprintf('Name of player can not be blank.'));
                    $isValid = false;
                }
                if(mb_strlen($player['name']) > 0 && (mb_strlen($player['name']) < 4 || mb_strlen($player['name']) > 255)){
                    ADS_MsgStack::push('error', sprintf('Name of player must be between %d and %d characters long.', 4, 255));
                    $isValid = false;
                }
                if(mb_strlen($player['name']) > 0 && (mb_strlen($player['clientKey']) < 6 || mb_strlen($player['clientKey']) > 128)){
                    ADS_MsgStack::push('error', sprintf('Client key must be between %d and %d characters long.', 6, 128));
                    $isValid = false;
                }
                if($clientKey !== $player['clientKey'] && $pModel->checkClientKey($player['clientKey'])){
                    ADS_MsgStack::push('error', sprintf('Client key already exists. Choose another one.', 6, 128));
                    $isValid = false;
                }
                //ready to go
                if($isValid){
                    //insert new player to db
                    $pModel->editPlayer($playerId, $player);
                    //log change
                    ADS_Logger::logChange('Player "%s" was updated.', $player['name']);
                    //redir
                    ADS_Navigator::redir('self:defaultAction',array(
                        'msg' => self::STATUS_EDIT_OK
                    ));
                }                
                break;                
        }  
        //add variables to output
        ADS_Output::register('player', $player);
        ADS_Output::register('errors', $errors);        
    }
    
    public function handleDefaultAction(){
        //get variables
        $page    =    (int)ADS_Input::getVar('paged', 1);
        $orderBy = (string)ADS_Input::getVar('orderBy', 'playerId');
        $order   = (string)ADS_Input::getVar('order', 'ASC');
        //prepare filter
        $status = (string)ADS_Input::getVar('status_valid', '-1');
        $filter = array(

        );
        //prepare sorting
        $rules = ads_prepare_sorting($orderBy, $order, array(
            'name', 'clientKey', 'status', 'lastSeen'
        ));        
        //load players
        $pModel = new ADS_PlayerModel();
        //count records
        $cnt = (int)$pModel->setFilter((array)@$filter[$status])->countPlayers();
        $players =  $pModel->setFilter((array)@$filter[$status])
                           ->setSorter($rules)
                           ->setPager($page)
                           ->getPlayers();
        //status online/offline        
        foreach($players as &$player){   
            $player->status = ((time() - strtotime($player->lastSeen)) < get_option('ads_player_offline_timeout', 300))?1:0; 
        }
        ADS_Output::register(
            'players',
            $players
        );        
        ADS_Output::register(
            'cnt',
            array(
                'all' => $pModel->setFilter(array())->countPlayers()
            )            
        );        
        //ADS_Debug::dump(ads_prepare_paging($page, $pModel->getLimit(), $cnt));
        ADS_Output::register(
            'pager',
            ads_prepare_paging($page, $pModel->getLimit(), $cnt)
        );
        //restore message
        $msg = (int)ADS_Input::getVar('msg', -1);
        if($msg === self::STATUS_ADD_OK){
            ADS_MsgStack::push('success', 'Player was successfully inserted.');
        }
        if($msg === self::STATUS_EDIT_OK){
            ADS_MsgStack::push('success', 'Player was successfully updated.');
        }
        if($msg === self::STATUS_REMOVE_OK){
            ADS_MsgStack::push('success', 'Player was successfully removed.');
        }
    }
    
    public function handleSendCommand(){
        //get variables
        $cmd      =      ADS_Input::getVar('cmd');
        $playerId = (int)ADS_Input::getVar('playerId', 0);
        //define allowed commands
        $allowedCommands = array (
            'restart', 'fullRestart', 'powerOff' 
        );
        //store command
        if(in_array($cmd, $allowedCommands)){
            $cModel = new ADS_CommandModel();
            $cModel->addCommand(array(
                'playerId' => $playerId,
                'cmd'      => $cmd,
                'recieved' => date('Y-m-d H:i:s')
            ));
        }
        //redir
        ADS_Navigator::redir('self:defaultAction',array(
            'msg' => self::STATUS_CMD_ADD_OK
        ));
        
    }
    
}